#include <stdlib.h>
#include <stdio.h>
#include "stringutils.h"
#include "arbrehuffman.h"
#include "listearbre.h"

arbre* creerMaillonAbr(char* lettre, int val, arbre* gch, arbre* dte, arbre* parent) {
    arbre* newArbre = malloc(sizeof (arbre));
    newArbre->lettre = lettre;
    newArbre->val = val;
    newArbre->gch = gch;
    newArbre->dte = dte;
    newArbre->parent = parent;
    if (dte != NULL) dte->parent = newArbre;
    if (gch != NULL) gch->parent = newArbre;
    return newArbre;
}

arbre* construireHuffman(liste** file) {
    if (estVide(*file))
        return NULL;

    arbre* a1 = pop(file);
    while (!estVide(*file)) {

        arbre* a2 = pop(file);
        arbre* temp = creerMaillonAbr(concat(a1->lettre, a2->lettre),
                a2->val + a1->val, a1, a2, NULL);
        insertionListe(file, temp);
        a1 = pop(file);
    }
    return a1;
}

void printarbre(arbre* a, int indentation) {
    if (a == NULL)
        return;

    for (int i = 0; i < indentation; i++)
        printf("  ");

    printf("%s\n", a->lettre);
    printarbre(a->gch, indentation + 1);
    printarbre(a->dte, indentation + 1);
}

arbre* genererNoeud(tableau* t, int* index, int niveau) {
    if (niveau > t->tab[*index].prof) {
        printf("Erreur dans le tableau des longueurs: %d - %s - %d\n", *index, t->tab[*index].lettre, t->nombre);
        exit(0);
    }
    if (t->tab[*index].prof == niveau) {
        arbre* a = creerMaillonAbr(t->tab[*index].lettre, 0, NULL, NULL, NULL);
        
        printf("LETTRE %d %d %d %s\n", *index, t->tab[*index].prof, niveau, t->tab[*index].lettre);
        (*index)++;
        return a;
    } else {
        //printf("NOEUD %d %d %d %s\n", *index, t->tab[*index].prof, niveau, t->tab[*index].lettre);
        arbre* dte = genererNoeud(t, index, niveau + 1);
        arbre* gch = genererNoeud(t, index, niveau + 1);
        char* label = concat(gch->lettre, dte->lettre);
        arbre* a = creerMaillonAbr(label, 0, gch, dte, NULL);
        gch->parent = dte->parent = a;

        return a;
    }
}

arbre* fromTableLongueur(tableau* t) {
    int i = 0;
    return genererNoeud(t, &i, 0);
}